package nancal.mp.model

import cn.hutool.core.text.AntPathMatcher
import nancal.mp.db.mongo.JenkinsLanguageEnum
import nancal.mp.db.mongo.MicroServiceDeployEnvEnum
import nancal.mp.db.mongo.entity.dev.AppDeploySetting
import nancal.mp.db.mongo.entity.dev.JenkinsBuildDetailInfo
import nancal.mp.db.mongo.entity.dev.JenkinsBuildInfo
import nancal.mp.db.mongo.entity.dev.JenkinsLog
import nancal.mp.db.mongo.extend.getAppDeploySetting
import nancal.mp.db.mongo.mor
import nbcp.base.extend.*
import nbcp.myoql.db.mongo.queryById

/**
 * k8s yaml 里的变量
 */
class K8sDeployServiceModel(
    var language: JenkinsLanguageEnum = JenkinsLanguageEnum.Java,
    var languageVersion: String = "",


    var productLineCode: String = "",

    /**
     * K8S label 中不能出现中文！
     */
    var productLineName: String = "",

    var buildInfo: JenkinsBuildInfo = JenkinsBuildInfo(),
    var buildVersion: JenkinsBuildDetailInfo = JenkinsBuildDetailInfo(),


    /**
     * 目标环境，dev,test,main
     */
    var targetEnv: String = ""
) {
    /**
     * 也是镜像名
     */
    val serviceName: String
        get() = buildInfo.serviceName

    val appName: String
        get() = buildInfo.appName

    val gitBranch: String
        get() = buildInfo.gitBranch

    val vpath: String
        get() = buildInfo.location

    val folder: String
        get() {
            var ret = this.buildInfo.buildFolder
            if (ret.startsWith("/")) {
                ret = ret.Slice(1);
            }

            if (ret.endsWith("/")) {
                ret = ret.Slice(0, -1)
            }

            if (ret.isEmpty()) {
                ret = "."
            }
            return ret;
        }


    /**
     * 镜像名， 不带前缀，不带版本号
     */
    val imageTagPrefix: String
        get() = buildInfo.imageTagPrefix

    val imageTagVersion: String
        get() = buildVersion.dockerImageVersion

    val dockerImageVersion: String
        get() = buildVersion.dockerImageVersion

//    val maxMemory: String
//        get() {
//            var ant = AntPathMatcher("-");
//            var languageSetting = mor.dev.appDeploySetting.getAppDeploySetting(targetEnv).languageSettings.first { it.language == this.language };
//
//            var resources = languageSetting.resourceSettings.firstOrNull {
//                return@firstOrNull ant.match(it.antPathMatcher,serviceName)
//            }?.requestMemory
//
//            if (memory.isNullOrEmpty()) {
//                memory = AppDeploySetting.getContainerDefaultMemories();
//            }
//
//            return memory.filter { it.language == language }.first().maxMemory.toString() + "Mi";
//        }


    val javaOpts: String
        get() {
            return mor.dev.appDeploySetting.getAppDeploySetting(targetEnv).javaOpts
        }

    val javaArgs: String
        get() {
            return mor.dev.appDeploySetting.getAppDeploySetting(targetEnv).javaArgs
        }

    /**
     * Dockerfile 中的基础镜像
     */
    val dockerBuildImage: String
        get() {
            return mor.dev.appDeploySetting.getAppDeploySetting(targetEnv)
                .getRunImageFullName(this.language!!, this.languageVersion)
        }

    val msDeployEnvEnum: MicroServiceDeployEnvEnum
        get() {
            return mor.dev.appDeploySetting.getAppDeploySetting(targetEnv).clusterDeployEnv
        }

    val profile: String
        get() {
            return mor.dev.appDeploySetting.getAppDeploySetting(targetEnv).profile
        }

    /**
     * 当前系统的配置， profile + 注册中心类型
     */
    val profiles: String
        get() {
            return setOf(this.profile.AsString(), this.msDeployEnvEnum.AsString())
                .filter { it.HasValue }
                .joinToString(",")
        }

    var namespace: String = ""
        get() {
            if (field.isNullOrEmpty()) return "default"
            return field;
        }
        set(value: String) {
            field = value;
        }

    val harborHost: String
        get() {
            return mor.dev.appDeploySetting.getAppDeploySetting(targetEnv).harborServer.host
        }

    val mount: String
        get() {
            if (mor.dev.appDeploySetting.getAppDeploySetting(targetEnv).k8sConfig.mountConfigmap) {
                return """
          configMap:
            name: ${this.appName}
""";
            }

            return """
          emptyDir: { }
""";
        }


    val fullImageVersion: String
        get() {
            return imageTagPrefix + serviceName + ":" + imageTagVersion
        }


    companion object {
        fun load(jenkinsLog: JenkinsLog): K8sDeployServiceModel {
            var productLine =
                mor.dev.productLine.queryById(jenkinsLog.productLine.id).toEntity().must()
                    .elseThrow { "找不到 productLine: " + jenkinsLog.productLine.id }

            var def = K8sDeployServiceModel();
            def.targetEnv = jenkinsLog.buildInfo.targetEnv
            def.language = jenkinsLog.language;
            def.languageVersion = jenkinsLog.languageVersion;
            def.namespace = productLine.clusterCode;
            def.productLineCode = jenkinsLog.productLine.code
            def.productLineName = jenkinsLog.productLine.name

            def.buildInfo = jenkinsLog.buildInfo;
            def.buildVersion = jenkinsLog.buildVersion;

            return def;
        }

        private fun getHalfMem(maxMemory: String): String {
            if (maxMemory.isBlank()) return maxMemory;

            var index = maxMemory.indexOfLast { it.isDigit() };
            if (index < 0) return maxMemory;

            var v = maxMemory.Slice(0, index + 1).AsInt() / 2;
            if (v == 0) return maxMemory;
            var u = maxMemory.Slice(index + 1);
            return v.toString() + u;
        }
    }
}
